package cn.ifanmi.findme.logic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import cn.ifanmi.findme.bean.Task;
import cn.ifanmi.findme.fanconst.JsonString;
import cn.ifanmi.findme.fanconst.SystemConst;

public class FanService extends Service implements Runnable {

	/**
	 * 主服务是否运行
	 */
	private boolean isRun;
	
	/**
	 * 后台处理网络请求的线程池中的线程数
	 */
	private static final int THREAD_COUNT = 3;
	
	/**
	 * 使用固定数量的线程池
	 * android普通应用用这样的就行了，没必要用ThreadPoolExecutor
	 */
	private ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
	
	/**
	 * 带堵塞的任务队列，是线程安全的。
	 * 是链表，也可以是ArrayBlockingQueue式的数组
	 */
	private static BlockingQueue<Task> tasks = new LinkedBlockingQueue<Task>();
	
	/**
	 * UI链表，其实就是activity和fragment。
	 * 因为只在尾部插入和删除，根据位置来遍历（当然也可以通过迭代器来遍历），
	 * 所以用array数组形式和linked链表形式都是可以的
	 */
	private static List<IfanUICommon> uiCommons = new ArrayList<IfanUICommon>();
	
	/**
	 * 执行各种任务的方法
	 * 只是不想让这个类太复杂
	 */
	private DoTaskService doTaskService = new DoTaskService();
	
	@SuppressLint("HandlerLeak")
	Handler handler = new Handler() {
		@SuppressWarnings("unchecked")
		public void handleMessage(android.os.Message msg) {
			String uiCommonName = msg.getData().getString(Task.FAN_UICOMMON);
			IfanUICommon uiCommon = getUICommonByName(uiCommonName);
			if (uiCommon != null) {
				uiCommon.refresh(msg.what, (Map<String, Object>)msg.obj);
			}
		}
	};
	
	@Override
	public void onCreate() {
		super.onCreate();
		startThreadPoll();
	}
	
	private void startThreadPoll() {
		isRun = true;
		for (int i = 0; i < THREAD_COUNT; i++) {
			executorService.execute(this);
		}
	}
	
	private void stopThreadPoll() {
		isRun = false;
		executorService.shutdown();
	}
	
	/**
	 * 添加任务到任务队列
	 * @param task	任务
	 */
	public static void addTask(Task task) {
		tasks.add(task);
	}
	
	@Override
	public void run() {
		while (isRun) {
			try {
				Task task = tasks.take();
				if (task.getTaskId() > Task.FAN_LOGIN_DIVIDER) {
					while (!SystemConst.isLogin) {
						Thread.sleep(1000);
					}
				} 
				doTask(task);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 执行网络任务
	 * @param task	任务
	 */
	private void doTask(Task task) {
		Message msg = new Message();
		msg.what = task.getTaskId();
		Map<String, Object> taskParams = task.getTaskParams();
		
		String uiCommon = (String) taskParams.get(Task.FAN_UICOMMON);
		msg.getData().putString(Task.FAN_UICOMMON, uiCommon);
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(JsonString.Return.RESULT, doTaskService.doTask(task));
		map.put(Task.FAN_MODE, (String) taskParams.get(Task.FAN_MODE));

		msg.obj = map;
		handler.sendMessage(msg);
	}
	
	public static void addUICommon(IfanUICommon uiCommon) {
		uiCommons.add(uiCommon);
	}
	
	public static void removeUICommon(IfanUICommon uiCommon) {
		uiCommons.remove(uiCommon);
	}
	
	private IfanUICommon getUICommonByName(String uiCommonName) {
		for (IfanUICommon uiCommon : uiCommons) {
			if (uiCommon.getClass().getSimpleName().equals(uiCommonName)) {
				return uiCommon;
			}
		}
		return null;
	}
	
	public static void emptyList() {
		uiCommons.clear();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	/**
	 * 在Service停止的时候，把线程池关了，让线程不再运行
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		stopThreadPoll();
	}

}
